home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-06-01 | 4.1 KB | 105 lines | [TEXT/CCL ] |
- ; Ted Kaehler and Dave Patterson: a taste of SmallTalk
- ; W. W. Norton ed., chapter 5, pp. 65 ff.
- ; translated in Allegro Common Lisp by Jean-Pascal J. LANGE.
- ; © Copyright 1988 Jean-Pascal J. LANGE.
-
- (proclaim '(optimize (speed 3)
- (space 0)
- (safety 0)
- (compilation-speed 0) ))
-
- (defStruct (animatedTowerOfHanoi (:include HanoiTower))
- #| This structure represents the game. It inherits the variable stacks
- from structure HanoiTower.
- The variables are:
- howMany: the number of disks,
- mockDisks: an array of fake disks (when a disk asks what disk it
- can move on top of, and the pole is empty, we return
- a mock disk; it has nearly infinite width). |#
- (howMany nil)
- (mockDisks nil) )
-
- ; the game
-
- (deFun animatedHanoi (animatedTower)
- ; asks the user how many disks, set up the game and move disks until
- ; we are done.
- (declare (special *TheTowers* *Thickness* *DiskGap*))
- (do ()
- ((integerp (howMany animatedTower)))
- (format t "~&Please type the number of disks in the tower: ")
- (setf (animatedTowerOfHanoi-howMany animatedTower) (read)) )
- (oneOf *window*
- :window-title "animated towers of Hanoï"
- :window-position #@(20 100)
- :window-size #@(360 220)
- :window-type :single-edge-box )
- (setUpDisks animatedTower) ; create the disks and stacks
- (moveTower animatedTower
- (howMany animatedTower) 1 3 2 )
- (setf (animatedTowerOfHanoi-howMany animatedTower) nil)
- (makUnbound '*TheTowers*)
- (makUnbound '*Thickness*)
- (makUnbound '*DiskGap*)
- nil ) ; animatedHanoi
-
- (deFun setUpDisks (animatedTower)
- ; Creates the disks and set up the poles. Tells all disks what game
- ; they are in and set disk thickness and gap.
- (whichTowers animatedTower)
- (let ((displayBox (originCorner #@(0 0)
- (ask (front-window) (window-size)) ) ) )
- (erase displayBox)
- (border displayBox 2) )
- ; the poles are an array of three stacks. Each stack is a list.
- (setf (animatedTowerOfHanoi-stacks animatedTower)
- (make-array 3 :initial-element nil) )
- (let ((disk)
- (size (howMany animatedTower)) )
- (doTimes (i (howMany animatedTower))
- (setq disk (make-HanoiDisk)) ; create a disk
- (widthPole disk size 1)
- ; don't forget: the first element of an array is at index 0 !!!
- (addFirst (animatedTowerOfHanoi-stacks animatedTower) 0 disk) ; push it onto a stack
- (invert disk) ; show on the screen
- (setq size (1- size)) ) )
-
- ; When a pole has no disk on it, one of these mock disks acts as a
- ; bottom disk. A moving disk will ask a mock disk its width and pole number.
- (setf (animatedTowerOfHanoi-mockDisks animatedTower)
- (make-array 3 :initial-element nil) )
- (let ((disk))
- (doTimes (index 3)
- (setq disk (make-HanoiDisk))
- ; don't forget: a doTimes-loop index starts at 0 !!!
- (widthPole disk 1000 (1+ index))
- ; don't forget: the first element of an array is at index 0 !!!
- (setf
- (aRef (animatedTowerOfHanoi-mockDisks animatedTower) index)
- disk ) ) ) )
-
- (deFun moveDisk (animatedTower fromPin toPin)
- ; move disk from a pin to another pin.
- ; Print the results in the listener window.
- (let ((supportDisk
- ; don't forget: the first element of an array is at index 0 !
- (if (aRef (animatedTowerOfHanoi-stacks animatedTower)
- (1- toPin) )
- (car (aRef (animatedTowerOfHanoi-stacks animatedTower)
- (1- toPin) ))
- (aRef (animatedTowerOfHanoi-mockDisks animatedTower)
- (1- toPin)) ) )
- (disk (getAndRemoveFirst
- (animatedTowerOfHanoi-stacks animatedTower)
- (1- fromPin) )) )
- (addFirst (animatedTowerOfHanoi-stacks animatedTower)
- (1- toPin) disk)
- ; inform the disk and show move
- (moveUpon disk supportDisk)
- #|(format t "~&~D -> ~D: ~A" fromPin toPin (name disk))|# )
- #|(sleep 0.3)|# ) ; moveDisk
-
- (deFun howMany (animatedTower)
- ; returns the number of disks
- (animatedTowerOfHanoi-howMany animatedTower) )
-